home *** CD-ROM | disk | FTP | other *** search
Text File | 1990-02-26 | 73.0 KB | 2,591 lines |
- Newsgroups: comp.sources.misc
- organization: Cognos Inc., Ottawa, Canada
- subject: v10i089: XLisP 2.1 sources 1b (2/3) / 5
- From: garym@cognos.UUCP (Gary Murphy)
- Sender: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)
-
- Posting-number: Volume 10, Issue 89
- Submitted-by: garym@cognos.UUCP (Gary Murphy)
- Archive-name: xlisp21/part02
-
- #!/bin/sh
- # This is a shell archive, meaning:
- # 1. Remove everything above the #!/bin/sh line.
- # 2. Save the resulting text in a file.
- # 3. Execute the file with /bin/sh (not csh) to create the files:
- # xl-001.bug
- # xl-002.bug
- # xl-003.bug
- # xl-004.bug
- # xl-005.bug
- # xl-006.bug
- # xl-cl001.fix
- # xl-xs001.bug
- # This archive created: Sun Feb 18 23:28:59 1990
- # By: Gary Murphy ()
- export PATH; PATH=/bin:$PATH
- echo shar: extracting "'xl-001.bug'" '(4674 characters)'
- if test -f 'xl-001.bug'
- then
- echo shar: over-writing existing file "'xl-001.bug'"
- fi
- sed 's/^X//' << \SHAR_EOF > 'xl-001.bug'
- XFrom sce!mitel!uunet!cs.utexas.edu!tut.cis.ohio-state.edu!ucbvax!hplabs!hplabsz!mayer Thu Jun 22 07:40:45 EDT 1989
- XArticle: 118 of comp.lang.lisp.x
- XPath: cognos!sce!mitel!uunet!cs.utexas.edu!tut.cis.ohio-state.edu!ucbvax!hplabs!hplabsz!mayer
- XFrom: mayer@hplabsz.HPL.HP.COM (Niels Mayer)
- XNewsgroups: comp.lang.lisp.x
- XSubject: Re: XLISP 2.0 -- bug in stream implementation // XLISP internals Docs?
- XMessage-ID: <3478@hplabsz.HPL.HP.COM>
- XDate: 14 Jun 89 05:10:28 GMT
- XReferences: <3468@hplabsz.HPL.HP.COM>
- XReply-To: mayer@hplabs.hp.com (Niels Mayer)
- XOrganization: Hewlett-Packard Labs, Software Technology Lab, Palo Alto, CA.
- XLines: 41
- XSummary:
- XExpires:
- XSender:
- XFollowup-To:
- X
- XIn article <3468@hplabsz.HPL.HP.COM> mayer@hplabs.hp.com (Niels Mayer) writes:
- X>It looks like garbage collection is trashing a pointer somewhere when using
- X>make-string-input-stream running read-char on that stream. After doing a
- X>bunch of read-chars on that stream, I get an "error: bad stream" message.
- X>This happens more often right after you start up xlisp, and less frequently
- X>upon subsequent garbage collections.
- X
- XSomeone inside HP kindly mailed me an archive of the last year of
- Xcomp.lang.lisp.x, and inside that archive, I found the following fix:
- X
- X Note 58 two bugs with unnamed streams in xlisp 2.0
- X nikkie@dutesta.UUCP (Paul A.W. van Niekerk) 7:13 am Dec 16, 1988
- X
- X I discovered two bugs in my copy of xlisp 2.0 concerning unnamed streams.
- X The bugs + fixes follow.
- X
- X 1. Unnamed streams never survive a garbage collection.
- X Fix: in xldmem.c change in function mark the line:
- X if ((type = ntype(this)) == CONS) {
- X to
- X if ((type = ntype(this)) == CONS || type == USTREAM) {
- X
- X 2. (format nil ...) does not protect the unnamed stream it creates, it will
- X vanish during a GC.
- X Fix: in xlfio.c add to function xformat the lines:
- X xlsave1(val);
- X ...
- X xlpop();
- X
- X Now USTREAMS seem to work fine.
- X Paul van Niekerk.
- X --
- X Paul A.W. van Niekerk | All standard
- X Delft University of Technology | disclaimers apply ...
- X
- X-------------------------------------------------------------------------------
- X Niels Mayer -- hplabs!mayer -- mayer@hplabs.hp.com
- X Human-Computer Interaction Department
- X Hewlett-Packard Laboratories
- X Palo Alto, CA.
- X *
- X
- X
- XFrom sce!mitel!uunet!cs.utexas.edu!csd4.milw.wisc.edu!dogie.macc.wisc.edu!indri!nero!blake!uw-beaver!tektronix!tekcrl!tekgvs!toma Thu Jun 22 07:41:11 EDT 1989
- XArticle: 119 of comp.lang.lisp.x
- XPath: cognos!sce!mitel!uunet!cs.utexas.edu!csd4.milw.wisc.edu!dogie.macc.wisc.edu!indri!nero!blake!uw-beaver!tektronix!tekcrl!tekgvs!toma
- XFrom: toma@tekgvs.LABS.TEK.COM (Tom Almy)
- XNewsgroups: comp.lang.lisp.x
- XSubject: Re: XLISP 2.0 -- bug in stream implementation // XLISP internals Docs?
- XMessage-ID: <5353@tekgvs.LABS.TEK.COM>
- XDate: 14 Jun 89 14:41:38 GMT
- XReferences: <3468@hplabsz.HPL.HP.COM>
- XReply-To: toma@tekgvs.LABS.TEK.COM (Tom Almy)
- XOrganization: Tektronix, Inc., Beaverton, OR.
- XLines: 39
- X
- XIn article <3468@hplabsz.HPL.HP.COM> mayer@hplabs.hp.com (Niels Mayer) writes:
- X>It looks like garbage collection is trashing a pointer somewhere when using
- X>make-string-input-stream running read-char on that stream. A[...]
- X
- X>I'm going to try to track this down in the code, but I thought I'd tap your
- X>collective wisdoms on this problem. Maybe someone's already fixed it? [...]
- X
- XYes the fix has been posted. An abridged copy is appended to this posting.
- X
- XTom Almy
- Xtoma@tekgvs.labs.tek.com
- XStandard Disclaimers Apply
- X
- X----------------------- OLD POSTING FOLLOWS --------------------------
- X
- XFrom: nikkie@dutesta.UUCP (Paul A.W. van Niekerk)
- XNewsgroups: comp.lang.lisp.x
- XSubject: two bugs with unnamed streams in xlisp 2.0
- XDate: 16 Dec 88 15:13:26 GMT
- XOrganization: DELFT UNIVERSITY OF TECHNOLOGY
- X Faculty of Electrical Engineering
- X Computer architecture and Digital Technique
- X Mekelweg 4 - 2628 CD Delft
- X
- XI discovered two bugs in my copy of xlisp 2.0 concerning unnamed streams.
- XThe bugs + fixes follow.
- X
- X1. Unnamed streams never survive a garbage collection.
- X Fix: in xldmem.c change in function mark the line:
- X if ((type = ntype(this)) == CONS) {
- X to
- X if ((type = ntype(this)) == CONS || type == USTREAM) {
- X
- X2. (format nil ...) does not protect the unnamed stream it creates, it will
- X vanish during a GC.
- X Fix: in xlfio.c add to function xformat the lines:
- X xlsave1(val);
- X ...
- X xlpop();
- X
- XNOTES: xlsave1(val) is being passed an uninitialized value! where do the
- X above xlsave1/xlpop go? pop before return?
- SHAR_EOF
- if test 4674 -ne "`wc -c 'xl-001.bug'`"
- then
- echo shar: error transmitting "'xl-001.bug'" '(should have been 4674 characters)'
- fi
- echo shar: extracting "'xl-002.bug'" '(8590 characters)'
- if test -f 'xl-002.bug'
- then
- echo shar: over-writing existing file "'xl-002.bug'"
- fi
- sed 's/^X//' << \SHAR_EOF > 'xl-002.bug'
- XFrom sce!mitel!uunet!cs.utexas.edu!tut.cis.ohio-state.edu!unmvax!ogccse!blake!uw-beaver!tektronix!zephyr.ens.tek.com!tekcrl!tekgvs!toma Tue Aug 29 08:42:34 EDT 1989
- XArticle: 139 of comp.lang.lisp.x
- XPath: cognos!sce!mitel!uunet!cs.utexas.edu!tut.cis.ohio-state.edu!unmvax!ogccse!blake!uw-beaver!tektronix!zephyr.ens.tek.com!tekcrl!tekgvs!toma
- XFrom: toma@tekgvs.LABS.TEK.COM (Tom Almy)
- XNewsgroups: comp.lang.lisp.x
- XSubject: Some Xlisp 2.0 read/print bugs
- XMessage-ID: <5818@tekgvs.LABS.TEK.COM>
- XDate: 24 Aug 89 15:44:30 GMT
- XReply-To: toma@tekgvs.LABS.TEK.COM (Tom Almy)
- XOrganization: Tektronix, Inc., Beaverton, OR.
- XLines: 262
- XPosted: Thu Aug 24 08:44:30 1989
- X
- XI discovered these problems with characters, strings, and symbols while
- Xworking on some Common Lisp-like enhancements.
- X
- X(I will post the enhancements when finished. These include COERCE,
- XCONCATENATE, and enhancements to functions that CL states take sequence
- Xarguments (lists, arrays, or strings in XLISP case) which XLISP implements
- Xtypically only for lists (except for SUBSEQ which only works on strings).
- X
- X
- XProblem: Uninterned symbols do not print with leading #:
- XExample: (GENSYM)
- XFix:
- X
- X1) At the beginning of xlprint, replace the code to print NIL with:
- X
- X /* print nil */
- X if (vptr == NIL) {
- X xlputstr(fptr,
- X (((!flag) || (getvalue(s_printcase) != k_downcase))?"NIL":"nil"));
- X return;
- X }
- X
- X2) In putsymbol, add these declarations:
- X
- X int i;
- X LVAL sym,array;
- X
- X3> In putsymbol, add the following *after* the code section titled "check
- X for printing without escapes":
- X
- X /* check for uninterned symbol */
- X i = hash(str,HSIZE);
- X array = getvalue(obarray);
- X for (sym = getelement(array,i);sym; sym = cdr(sym))
- X if (strcmp(str,(char*)getstring(getpname(car(sym)))) == 0)
- X goto internedSymbol;
- X
- X xlputc(fptr,'#'); /* indicate uninterned */
- X xlputc(fptr,':');
- X
- XinternedSymbol: /* sorry about the "goto" */
- X
- X
- X*******************************************************************
- X
- XProblem: strings containing nulls cannot be read or printed.
- X(Note, strcat has the same problem, but I have a new version, the
- X Common Lisp CONCATENATE function, which will replace it.
- X
- X
- XExample: Enter "A string\000will forget these"
- X
- XFix:
- X
- X1) In rmdquote change section "check for buffer overflow" to:
- X
- X if (blen >= STRMAX) {
- X newstr = newstring(len + STRMAX + 1);
- X sptr = getstring(newstr);
- X if (str) memcpy((char *)sptr,(char *)getstring(str),len);
- X *p = '\0';
- X memcpy((char *)sptr+len,(char *)buf,blen+1);
- X p = buf;
- X blen = 0;
- X len += STRMAX;
- X str = newstr;
- X }
- X
- X2) In rmdquote, change section "append the last substring" to:
- X
- X if (str == NIL || blen) {
- X newstr = newstring(len + blen + 1);
- X sptr = getstring(newstr);
- X if (str) memcpy((char *)sptr,(char *)getstring(str),len);
- X *p = '\0';
- X memcpy((char *)sptr+len,(char *)buf,blen+1);
- X str = newstr;
- X }
- X
- X3) New versions of putstring and putqstring
- X
- X
- X/* putstring - output a string */
- X/* rewritten to print strings containing nulls TAA mod*/
- XLOCAL VOID putstring(fptr,str)
- X LVAL fptr,str;
- X{
- X unsigned char* p = getstring(str);
- X int len = getslength(str) - 1;
- X
- X /* output each character */
- X while (len-- > 0) xlputc(fptr,*p++);
- X}
- X
- X/* putqstring - output a quoted string */
- X/* rewritten to print strings containing nulls TAA mod*/
- XLOCAL VOID putqstring(fptr,str)
- X LVAL fptr,str;
- X{
- X unsigned char* p = getstring(str);
- X int len = getslength(str) - 1;
- X int ch;
- X
- X /* output the initial quote */
- X xlputc(fptr,'"');
- X
- X /* output each character in the string */
- X while (len-- > 0) {
- X ch = *p++;
- X
- X /* check for a control character */
- X if (ch < 040 || ch == '\\' || ch > 0176) {
- X xlputc(fptr,'\\');
- X switch (ch) {
- X case '\011':
- X xlputc(fptr,'t');
- X break;
- X case '\012':
- X xlputc(fptr,'n');
- X break;
- X case '\014':
- X xlputc(fptr,'f');
- X break;
- X case '\015':
- X xlputc(fptr,'r');
- X break;
- X case '\\':
- X xlputc(fptr,'\\');
- X break;
- X default:
- X putoct(fptr,ch);
- X break;
- X }
- X }
- X
- X /* output a normal character */
- X else
- X xlputc(fptr,ch);
- X }
- X
- X
- X /* output the terminating quote */
- X xlputc(fptr,'"');
- X}
- X
- X
- X********************************************
- X
- XProblem: Control and meta characters print "raw" with prin1.
- X
- XExample: Execute (int-char 7)
- X
- XFix: New version of putchcode:
- X
- X/* putchcode - output a character */
- X/* modified to print control and meta characters TAA Mod */
- X/* Format: #\[M-][C-]c
- X Where "M-" denotes character is meta character (value > 127).
- X "C-" denotes character is control character ( value modulo 128 < 32)
- X and "c" is either a printing character or "Space", "Newline", or "Rubout".
- X*/
- X
- X
- XLOCAL VOID putchcode(fptr,ch,escflag)
- X LVAL fptr; int ch,escflag;
- X{
- X if (escflag) {
- X xlputstr(fptr,"#\\");
- X if (ch > 127) {
- X ch -= 128;
- X xlputstr(fptr,"M-");
- X }
- X switch (ch) {
- X case '\n':
- X xlputstr(fptr,"Newline");
- X break;
- X case ' ':
- X xlputstr(fptr,"Space");
- X break;
- X case 127:
- X xlputstr(fptr,"Rubout");
- X break;
- X default:
- X if (ch < 32) {
- X ch += '@';
- X xlputstr(fptr,"C-");
- X }
- X xlputc(fptr,ch);
- X break;
- X }
- X }
- X else xlputc(fptr,ch);
- X}
- X
- X*******************************************
- X
- XProblem: Inability to declare character literals for control and meta
- X characters.
- X
- XFix: in rmhash(), first add declaration "int i", then
- X change case '\\' code to:
- X
- X case '\\':
- X for (i = 0; i < STRMAX-1; i++) {
- X if ((tentry(buf[i] = checkeof(fptr)) != k_const) &&
- X buf[i] != '\\' && buf[i] != '|') {
- X xlungetc(fptr, buf[i]);
- X break;
- X }
- X }
- X buf[i] = 0;
- X
- X ch = buf[0];
- X if (strlen(buf) > 1) {
- X upcase(buf);
- X bufp = &buf[0];
- X ch = 0;
- X if (strncmp(bufp,"M-",2) == 0) {
- X ch = 128;
- X bufp += 2;
- X }
- X if (strcmp(bufp,"NEWLINE") == 0)
- X ch += '\n';
- X else if (strcmp(bufp,"SPACE") == 0)
- X ch += ' ';
- X else if (strcmp(bufp,"RUBOUT") == 0)
- X ch += 127;
- X else if (strlen(bufp) == 1)
- X ch += *bufp;
- X else if (strncmp(bufp,"C-",2) == 0 && strlen(bufp) == 3)
- X ch += bufp[2] & 31;
- X else xlerror("unknown character name",cvstring(buf));
- X }
- X rplaca(val,cvchar(ch));
- X break;
- X
- X***********************************************
- X
- XProblem: Invalid symbols can be created with intern and make-symbol.
- X Also, you can make NIL, which is highly irregular.
- X
- XExample: (intern "abc\017def") (intern "NIL")
- X
- X
- XFix: Add to makesymbol(), before section "make the symbol":
- X
- X /* check for making "NIL" -- very bad */
- X if (strcmp((char *)getstring(pname),"NIL") == 0)
- X xlerror("you've got to be kidding!");
- X
- X /* check for containing only printable characters */
- X i = getslength(pname)-1;
- X while (i-- > 0) if (((signed char)(pname->n_string[i])) < 32 )
- X xlerror("string contains non-printing characters",pname);
- X
- X
- X
- X*****************
- X
- XTom Almy
- Xtoma@tekgvs.labs.tek.com
- XStandard Disclaimers Apply
- X
- X
- XFrom sce!mitel!uunet!zephyr.ens.tek.com!tekcrl!tekgvs!toma Tue Aug 29 11:30:44 EDT 1989
- XArticle: 140 of comp.lang.lisp.x
- XPath: cognos!sce!mitel!uunet!zephyr.ens.tek.com!tekcrl!tekgvs!toma
- XFrom: toma@tekgvs.LABS.TEK.COM (Tom Almy)
- XNewsgroups: comp.lang.lisp.x
- XSubject: Yet Another XLISP Bug
- XMessage-ID: <5824@tekgvs.LABS.TEK.COM>
- XDate: 25 Aug 89 14:37:30 GMT
- XReply-To: toma@tekgvs.LABS.TEK.COM (Tom Almy)
- XOrganization: Tektronix, Inc., Beaverton, OR.
- XLines: 13
- X
- X
- XProblem: Functions NTH and NTHCDR give errors when applied to zero length
- X lists.
- X
- XExample: (NTH 1 '())
- X
- XFix: In function nth(), replace call of xlgacons() with xlgalist()
- X
- X(That was simple, wasn't it?)
- X
- XTom Almy
- Xtoma@tekgvs.labs.tek.com
- XStandard Disclaimers Apply
- X
- X
- SHAR_EOF
- if test 8590 -ne "`wc -c 'xl-002.bug'`"
- then
- echo shar: error transmitting "'xl-002.bug'" '(should have been 8590 characters)'
- fi
- echo shar: extracting "'xl-003.bug'" '(3526 characters)'
- if test -f 'xl-003.bug'
- then
- echo shar: over-writing existing file "'xl-003.bug'"
- fi
- sed 's/^X//' << \SHAR_EOF > 'xl-003.bug'
- XFrom sce!mitel!uunet!cs.utexas.edu!tut.cis.ohio-state.edu!ucbvax!hplabs!hplabsz!mayer Fri Sep 1 08:29:10 EDT 1989
- XArticle: 141 of comp.lang.lisp.x
- XPath: cognos!sce!mitel!uunet!cs.utexas.edu!tut.cis.ohio-state.edu!ucbvax!hplabs!hplabsz!mayer
- XFrom: mayer@hplabsz.HPL.HP.COM (Niels Mayer)
- XNewsgroups: comp.lang.lisp.x,comp.lang.lisp
- XSubject: Bug+Fix for xlisp2.0 method definition <-> Question: Should "defmethod" and "defmacro" use lexical scoping
- XMessage-ID: <3860@hplabsz.HPL.HP.COM>
- XDate: 26 Aug 89 13:37:22 GMT
- XReply-To: mayer@hplabs.hp.com (Niels Mayer)
- XOrganization: Hewlett-Packard Labs, Software Technology Lab, Palo Alto, CA.
- XLines: 83
- XXref: cognos comp.lang.lisp.x:141 comp.lang.lisp:1787
- XSummary:
- XExpires:
- XSender:
- XFollowup-To:
- X
- XIn looking over the xlisp 2.0 objects code, I found a problem in
- Xxlobj.c:clanswer() in which I noticed that the :answer method on class
- XClass does not save the lexical (xlenv) and functional (xlfenv)
- Xenvironments in the closure created by xlclose() during method definition.
- XThus, when the method gets evaluated, you get unbound symbol/function
- Xerrors because the environment of the method call doesn't contain the
- Xbindings present in the definition's environment. [For you non xlispers
- Xout there, :answer defines a method on a class (essentially, a
- X"defmethod").]
- X
- XBefore I commit to my fix, I wanted to ask you all whether there is a good
- Xreason for NOT using the lexical and functional environment of a call to
- X"defmethod" during a method evaluation.
- X
- XI would expect that you'd want to use lexical scoping for defining methods
- Xjust like you would for defuns and lambdas. But I've been surprised before.
- X
- XAnother case in which xlclose() isn't passed xlenv and xlfenv is in
- Xxlcont.c:xdefmacro(). Is there a reason why you wouldn't want to pass
- Xin the lexical environment of a call to defmacro?
- X
- X ----------
- X
- XHere's some useless test code that illustrates the problem:
- X
- X lisp> (setq test_class (send Class :new '(a b c) '()))
- X lisp> (let (
- X (x 666)
- X (y 777)
- X (z 888))
- X (send test_class :answer :isnew '() ;initialize method
- X '(
- X (setq a x)
- X (setq b y)
- X (setq c z)
- X ))
- X )
- X lisp> (setq i (send test_class :new))
- X
- XNow, upon sending the :new message, I get the error mesage
- X
- X lisp> error: unbound variable - X
- X
- XAfter fixing the code in xlobj.c:clanswer(), I get the correct results:
- X
- X lisp> (send i :show)
- X lisp> Object is #<Object: #136002>, Class is #<Object: #127f40>
- X lisp> A = 666
- X lisp> B = 777
- X lisp> C = 888
- X lisp> #<Object: #136002>
- X
- X ----------
- X
- XHere's the patch:
- X
- X*** xlobj.c.~1~ Sat Aug 26 06:14:33 1989
- X--- xlobj.c Sat Aug 26 06:16:24 1989
- X***************
- X*** 277,283
- X /* setup the message node */
- X xlprot1(fargs);
- X fargs = cons(s_self,fargs); /* add 'self' as the first argument */
- X! rplacd(mptr,xlclose(msg,s_lambda,fargs,code,NIL,NIL));
- X xlpop();
- X
- X /* return the object */
- X
- X--- 277,283 -----
- X /* setup the message node */
- X xlprot1(fargs);
- X fargs = cons(s_self,fargs); /* add 'self' as the first argument */
- X! rplacd(mptr,xlclose(msg,s_lambda,fargs,code,xlenv,xlfenv)); /* changed by NPM -- pass in lexical and functional environment */
- X xlpop();
- X
- X /* return the object */
- X
- X-------------------------------------------------------------------------------
- X Niels Mayer -- hplabs!mayer -- mayer@hplabs.hp.com
- X Human-Computer Interaction Department
- X Hewlett-Packard Laboratories
- X Palo Alto, CA.
- X *
- X
- X
- SHAR_EOF
- if test 3526 -ne "`wc -c 'xl-003.bug'`"
- then
- echo shar: error transmitting "'xl-003.bug'" '(should have been 3526 characters)'
- fi
- echo shar: extracting "'xl-004.bug'" '(2058 characters)'
- if test -f 'xl-004.bug'
- then
- echo shar: over-writing existing file "'xl-004.bug'"
- fi
- sed 's/^X//' << \SHAR_EOF > 'xl-004.bug'
- XFrom sce!mitel!uunet!zephyr.ens.tek.com!tekcrl!tekgvs!toma Sun Sep 10 21:19:10 EDT 1989
- XArticle: 148 of comp.lang.lisp.x
- XPath: cognos!sce!mitel!uunet!zephyr.ens.tek.com!tekcrl!tekgvs!toma
- XFrom: toma@tekgvs.LABS.TEK.COM (Tom Almy)
- XNewsgroups: comp.lang.lisp.x
- XSubject: save/restore bug fixes!
- XMessage-ID: <5886@tekgvs.LABS.TEK.COM>
- XDate: 6 Sep 89 13:53:17 GMT
- XReply-To: toma@tekgvs.LABS.TEK.COM (Tom Almy)
- XOrganization: Tektronix, Inc., Beaverton, OR.
- XLines: 56
- X
- XOK, so it was pretty schlocky of me to mention my previous fix postings
- Xrather than posting the fixes. I was just too busy to look them up.
- X
- XThere is no promise that these changes will fix the problem with xscheme,
- Xbut there does seem to be numerous bugs that are in both x's.
- X
- XTom Almy
- Xtoma@tekgvs.labs.tek.com
- X
- X
- X
- X*******************
- XProblem: "restore" corrupts system.
- XDiagnosis: argument stack not being reset -- initial garbage collect
- X "marks" random memory!
- X
- XSolution: Add to "initialize" in xlirestore:
- X
- X
- X xlfp = xlsp = xlargstkbase;
- X *xlsp++ = NIL;
- X
- X
- X
- X*******************
- XProblem: "restore" corrupts system with 8086 compilers.
- XDiagnosis: cvoptr is doing improper arithmetic.
- X
- XSolution: CVPTR in xlisp.h needs to be defined as
- X#define CVPTR(x) ((((unsigned long)(x) >> 16) << 4) + ((unsigned) x))
- X
- X return statement in cvoptr() (xlimage.c) needs to be changed from:
- Xreturn (off + (OFFTYPE)((p - seg->sg_nodes) << 1));
- X to:
- Xreturn (off+(((CVPTR(p)-CVPTR(seg->sg_nodes))/sizeof(struct node))<<1));
- X
- X
- XNote: for this to work with non-8086 compilers, the default for CVPTR
- Xshould be changed from (x) to ((OFFTYPE)(x)).
- X
- X
- X*******************
- XA third problem that caused more than one restore in a session to fail had
- Xbeen fixed already in xscheme. For the record, though:
- X
- XBUG: Any attempt to do more than one RESTORE in a session causes the error
- X "insufficient memory - segment".
- X
- XIn file xlimage.c, function freeimage(), change
- X
- X if (((fp = getfile(p)) != 0) && (fp != stdin && fp != stdout))
- X
- Xto:
- X
- X if (((fp = getfile(p)) != 0) &&
- X (fp != stdin && fp != stdout && fp != stderr))
- X
- X
- SHAR_EOF
- if test 2058 -ne "`wc -c 'xl-004.bug'`"
- then
- echo shar: error transmitting "'xl-004.bug'" '(should have been 2058 characters)'
- fi
- echo shar: extracting "'xl-005.bug'" '(3003 characters)'
- if test -f 'xl-005.bug'
- then
- echo shar: over-writing existing file "'xl-005.bug'"
- fi
- sed 's/^X//' << \SHAR_EOF > 'xl-005.bug'
- XFrom sce!mitel!uunet!zephyr.ens.tek.com!tekcrl!tekgvs!toma Wed Jan 17 09:56:12 EST 1990
- XArticle: 53 of comp.lang.lisp.x
- XPath: cognos!sce!mitel!uunet!zephyr.ens.tek.com!tekcrl!tekgvs!toma
- XFrom: toma@tekgvs.LABS.TEK.COM (Tom Almy)
- XNewsgroups: comp.lang.lisp.x
- XSubject: Some More bug fixes
- XMessage-ID: <6670@tekgvs.LABS.TEK.COM>
- XDate: 15 Jan 90 18:27:05 GMT
- XReply-To: toma@tekgvs.LABS.TEK.COM (Tom Almy)
- XOrganization: Tektronix, Inc., Beaverton, OR.
- XLines: 134
- X
- XThese problems were pointed out to me by Paul van Niekerk
- X(nikkie@duteca2.tudelft.nl). They are applicable to XLISP versions 2.0 or 2.1.
- X
- XPROBLEM: (last '(a b . c)) returns c rather than (b . c)
- XSOLUTION: in xllist.c, replace xlast with:
- X
- X/* xlast - return the last cons of a list */
- XLVAL xlast()
- X{
- X LVAL list;
- X
- X /* get the list */
- X list = xlgalist();
- X xllastarg();
- X
- X /* find the last cons */
- X if (consp(list))
- X while (consp(cdr(list))) list = cdr(list);
- X
- X /* return the last element */
- X return (list);
- X}
- X
- XPROBLEM: functions boundp, fboundp, symbol-name, symbol-value, and
- Xsymbol-plist fail on NIL (which *is* a symbol), and symbol-function fails
- Ximproperly (wrong error message).
- X
- XSOLUTION:
- X
- XIn xlisp.h, add:
- X
- X#define xlgasymornil() (*xlargv==NIL || symbolp(*xlargv) ? nextarg() : xlbadtype(*xlargv))
- X
- XIn xlbfun.c, change functions to the following:
- X
- X/* xboundp - is this a value bound to this symbol? */
- XLVAL xboundp()
- X{
- X LVAL sym;
- X sym = xlgasymornil();
- X xllastarg();
- X return (sym == NIL || boundp(sym) ? true : NIL);
- X}
- X
- X/* xfboundp - is this a functional value bound to this symbol? */
- XLVAL xfboundp()
- X{
- X LVAL sym;
- X sym = xlgasymornil();
- X xllastarg();
- X return (sym != NIL && fboundp(sym) ? true : NIL);
- X}
- X
- X/* xsymname - get the print name of a symbol */
- XLVAL xsymname()
- X{
- X LVAL sym;
- X
- X /* get the symbol */
- X sym = xlgasymornil();
- X xllastarg();
- X
- X /* handle NIL, which is not internally represented as a symbol */
- X if (sym == NIL) {
- X sym = newstring(4);
- X strcpy(getstring(sym), "NIL");
- X return sym;
- X }
- X
- X /* return the print name */
- X return (getpname(sym));
- X}
- X
- X/* xsymvalue - get the value of a symbol */
- XLVAL xsymvalue()
- X{
- X LVAL sym,val;
- X
- X /* get the symbol */
- X sym = xlgasymornil();
- X xllastarg();
- X
- X /* handle NIL */
- X if (sym == NIL) return (NIL);
- X
- X /* get the global value */
- X while ((val = getvalue(sym)) == s_unbound)
- X xlunbound(sym);
- X
- X /* return its value */
- X return (val);
- X}
- X
- X/* xsymfunction - get the functional value of a symbol */
- XLVAL xsymfunction()
- X{
- X LVAL sym,val;
- X
- X /* get the symbol */
- X sym = xlgasymornil();
- X xllastarg();
- X
- X /* handle NIL */
- X if (sym == NIL) {
- X while (1)
- X xlfunbound(sym);
- X }
- X
- X
- X /* get the global value */
- X while ((val = getfunction(sym)) == s_unbound)
- X xlfunbound(sym);
- X
- X /* return its value */
- X return (val);
- X}
- X
- X/* xsymplist - get the property list of a symbol */
- XLVAL xsymplist()
- X{
- X LVAL sym;
- X
- X /* get the symbol */
- X sym = xlgasymornil();
- X xllastarg();
- X
- X /* return the property list */
- X return (sym == NIL ? NIL : getplist(sym));
- X}
- X
- X
- XTom Almy
- Xtoma@tekgvs.labs.tek.com
- XStandard Disclaimers Apply
- X
- X
- SHAR_EOF
- if test 3003 -ne "`wc -c 'xl-005.bug'`"
- then
- echo shar: error transmitting "'xl-005.bug'" '(should have been 3003 characters)'
- fi
- echo shar: extracting "'xl-006.bug'" '(2689 characters)'
- if test -f 'xl-006.bug'
- then
- echo shar: over-writing existing file "'xl-006.bug'"
- fi
- sed 's/^X//' << \SHAR_EOF > 'xl-006.bug'
- XFrom sce!mitel!uunet!zephyr.ens.tek.com!tekcrl!tekgvs!toma Thu Dec 7 08:52:22 EST 1989
- XArticle: 42 of comp.lang.lisp.x
- XPath: cognos!sce!mitel!uunet!zephyr.ens.tek.com!tekcrl!tekgvs!toma
- XFrom: toma@tekgvs.LABS.TEK.COM (Tom Almy)
- XNewsgroups: comp.lang.lisp.x
- XSubject: More XLISP Bugs
- XMessage-ID: <6460@tekgvs.LABS.TEK.COM>
- XDate: 4 Dec 89 18:18:34 GMT
- XReply-To: toma@tekgvs.LABS.TEK.COM (Tom Almy)
- XOrganization: Tektronix, Inc., Beaverton, OR.
- XLines: 110
- X
- X
- X 12/4/89
- X
- XI was trying some examples in Common Lisp: The Reference, and found some
- Xbugs (both real and compatibility) in XLISP 2.0/2.1
- X
- X********************
- X
- XDouble quotes are not escaped when printing.
- X(Fix needed in putqstring to handle case of '"').
- X
- Xchange:
- X if (ch < 040 || ch == '\\' || ch > 0176) {
- Xto:
- X if (ch < 040 || ch == '\\' || ch == '"' || ch > 0176) {
- X
- Xchange:
- X case '\\':
- X xlputc(fptr,'\\');
- X break;
- X
- Xto:
- X case '\\':
- X case '"':
- X xlputc(fptr,ch);
- X break;
- X
- X******************
- XIn version 2.1, #S() construct doesn't quote element values.
- X":" not allowed on keywords, nor are the printed.
- X
- XExample:
- X
- X(defstruct foo (x 10))
- X
- X
- X#S(foo) prints #S(foo x 10) instead of #S(foo :x 10)
- X
- X#S(foo :x 10) gives an error
- X
- X#S(foo x (+ 3 4)) gives #S(foo x 7) instead of #S(foo :x (+3 4))
- X
- XIn xlrdstruct() (xlstruct.c)
- X
- Xchange:
- X sprintf(buf,":%s",getstring(getpname(slotname)));
- X
- X /* add the slot keyword */
- X rplacd(last,cons(xlenter(buf),NIL));
- X
- Xto:
- X
- X
- X /* add the slot keyword */
- X if (*(getstring(getpname(slotname))) != ':') { /* add colon */
- X sprintf(buf,":%s",getstring(getpname(slotname)));
- X rplacd(last,cons(xlenter(buf),NIL));
- X }
- X else {
- X rplacd(last,cons(slotname,NIL));
- X }
- X
- Xand change:
- X /* add the value expression */
- X rplacd(last,cons(car(list),NIL));
- X last = cdr(last);
- X list = cdr(list);
- X
- Xto:
- X /* add the value expression -- QUOTED (TAA MOD) */
- X rplacd(last,cons(NIL,NIL));
- X last = cdr(last);
- X rplaca(last, (slotname = cons(s_quote,NIL)));
- X rplacd(slotname, cons(car(list), NIL));
- X list = cdr(list);
- X
- X
- X
- XIn xlprstruct(), replace:
- X xlputc(fptr,' ');
- X
- Xwith:
- X xlputstr(fptr," :"); /* TAA MOD, colons should show */
- X
- X****************
- XIn XLISP 2.1, attempts to write to a structure element beyond the end of
- Xthe structure (i.e. wrong access function used) tends to cause a crash.
- X
- XFIX: in both xstrref() and xstrset() (in xlstruct.c)
- X
- Xafter:
- X xllastarg();
- X
- Xadd:
- X if (i >= getsize(str)) /* wrong structure*/
- X xlerror("Bad structure reference",str);
- X
- X
- X*********************
- XI added #. macro, to eval at read time.
- XTo switch statement in rmhash add:
- X
- X case '.':
- X readone(fptr,&car(val));
- X rplaca(val,xleval(car(val)));
- X break;
- X
- XTom Almy
- Xtoma@tekgvs.labs.tek.com
- XStandard Disclaimers Apply
- X
- X
- SHAR_EOF
- if test 2689 -ne "`wc -c 'xl-006.bug'`"
- then
- echo shar: error transmitting "'xl-006.bug'" '(should have been 2689 characters)'
- fi
- echo shar: extracting "'xl-cl001.fix'" '(41338 characters)'
- if test -f 'xl-cl001.fix'
- then
- echo shar: over-writing existing file "'xl-cl001.fix'"
- fi
- sed 's/^X//' << \SHAR_EOF > 'xl-cl001.fix'
- XFrom sce!mitel!uunet!zephyr.ens.tek.com!tekcrl!tekgvs!toma Sat Sep 16 08:20:18 EDT 1989
- XArticle: 1 of comp.lang.lisp.x
- XPath: cognos!sce!mitel!uunet!zephyr.ens.tek.com!tekcrl!tekgvs!toma
- XFrom: toma@tekgvs.LABS.TEK.COM (Tom Almy)
- XNewsgroups: comp.lang.lisp.x
- XSubject: XLISP 2.0 BUG(?)
- XMessage-ID: <5911@tekgvs.LABS.TEK.COM>
- XDate: 11 Sep 89 14:34:11 GMT
- XReply-To: toma@tekgvs.LABS.TEK.COM (Tom Almy)
- XOrganization: Tektronix, Inc., Beaverton, OR.
- XLines: 22
- X
- X
- XPart of my effort to make xlisp more compatible with Common Lisp:
- X
- XProblem: Functions which take the :end keyword argument do not allow NIL
- X to mean "end of list" as in Common Lisp.
- X
- XExample: (string-downcase "ABC DEF" :start 4 :end NIL) gives an error.
- X
- XFix: in function getbounds() in file xlstr.c, change
- X
- X if (xlgkfixnum(ekey,&arg)) {
- X *pend = (int)getfixnum(arg);
- X
- Xto
- X if (xlgetkeyarg(ekey, &arg) && arg != NIL) {
- X if (!fixp(arg)) xlbadtype(arg);
- X *pend = (int)getfixnum(arg);
- X
- X
- XTom Almy
- Xtoma@tekgvs.labs.tek.com
- XStandard Disclaimers Apply
- X
- X
- XFrom sce!mitel!uunet!zephyr.ens.tek.com!tekcrl!tekgvs!toma Sat Sep 16 08:20:26 EDT 1989
- XArticle: 2 of comp.lang.lisp.x
- XPath: cognos!sce!mitel!uunet!zephyr.ens.tek.com!tekcrl!tekgvs!toma
- XFrom: toma@tekgvs.LABS.TEK.COM (Tom Almy)
- XNewsgroups: comp.lang.lisp.x
- XSubject: XLISP 2.0 Modifications (1 of 2)
- XMessage-ID: <5918@tekgvs.LABS.TEK.COM>
- XDate: 11 Sep 89 22:25:11 GMT
- XReply-To: toma@tekgvs.LABS.TEK.COM (Tom Almy)
- XOrganization: Tektronix, Inc., Beaverton, OR.
- XLines: 393
- X
- XI have recently been adding a few Common Lisp functions to XLISP 2.0, and
- Xmakeing some existing functions more Common-Lisp compatible (particularly
- Xin making functions that are supposed to take sequence arguments (in XLISP
- Xthat would be lists, arrays, or strings) actually take them.
- X
- XThese changes produce the following consequences:
- X
- X1. Functions with names starting with "STRING" will accept a symbol as
- X the string argument. The symbols printname string is used.
- X
- X2. STRCAT is eliminated (a macro is placed in init.lsp for backwards
- X compatibility). The replacement function is CONCATENATE which will
- X concatenate sequences of any type(s) into a result sequence of any
- X type. It is used: (CONCATENATE <type> <seq1> [<seq2> ...]) where
- X type is the result type, one of CONS ARRAY or STRING.
- X
- X3. AREF will work on strings as well as arrays.
- X
- X4. SUBSEQ REVERSE REMOVE... DELETE... take sequence arguments rather
- X than just list arguments.
- X
- X5. REMOVE... and DELETE... accept :start and :end keyword arguments.
- X
- X6. Added function (ELT <seq> <index>) which combines the functionality
- X of AREF and NTH.
- X
- X7. Added function (MAP <type> <fcn> <seq1> [<seq2> ...]) a mapping
- X function over sequences. The resulting sequence is of type <type>,
- X which is one of CONS ARRAY STRING or NIL (meaning no, or NIL, result).
- X
- X8. Added functions POSITION-IF, FIND-IF, and COUNT-IF, which work
- X analogously to REMOVE-IF, but return the position of the first match,
- X the first match, and number of matches, respectively.
- X
- X9. Added function (SEARCH <seq1> <seq2> &key :test :test-not :start1
- X :end1 :start2 :end2) which returns the index of the first occurance
- X of seq1 in seq2. For example (search #(a b c) '(a b a b c d)) returns
- X 2.
- X
- X10. Added function (COERCE <expr> <type>) which can coerce between
- X sequence types and in a limited basis to characters or floating point
- X numbers.
- X
- X
- XThis is the first of two parts. The final line in this file is "This is
- Xthe end of part 1."
- X
- X
- XTom Almy
- XSeptember 11, 1989
- Xtoma@tekgvs.labs.tek.com
- XStandard Disclaimers Apply
- X
- X
- X***************************************
- XThe first change reduces the amount of code.
- X
- XIn xlsubr.c, add the following definition:
- X
- X/* xlbadtype - report a "bad argument type" error */
- XLVAL xlbadtype(arg)
- X LVAL arg;
- X{
- X return xlerror("bad argument type",arg);
- X}
- X
- X
- XThen replace all occurances of `xlerror("bad argument type",' with
- X`xlbadtype(' throughout the program (including xlisp.h).
- X
- X***************************************
- X
- XAdd the file xlseq.c to your "makefile" in an appropriate manner.
- X
- X***************************************
- XAdd definition in xlisp.h:
- X
- X#define xlgastrorsym() (testarg(symbolp(*xlargv) ? getpname(nextarg()) : typearg(stringp)))
- X
- XAdded external declaration in xlisp.h:
- Xextern LVAL xlbadtype(); /* report "bad argument type" error */
- X
- X
- X
- X***************************************
- XAdd to init.lsp:
- X(unless (fboundp 'strcat) ; backwards compatibility
- X (defmacro strcat (&rest str) `(concatenate 'string ,@str)))
- X
- X
- X
- X***************************************
- XIn xlftab.c, add the following external declaration:
- Xextern LVAL
- X xcoerce(), xconcatenate(), xelt(), xmap(), xsearch(), xpositionif(),
- X xcountif(),xfindif();
- X
- Xdelete the declaration for xstrcat.
- X
- XIn funtab[], replace the definition for STRCAT with:
- X
- X{ "CONCATENATE", S, xconcatenate }, /* 168 */
- X
- XReplace NULL definitions at the end of the table with new definitions,
- Xbeing sure to keep the table length constant.
- X
- X{ "COUNT-IF", S, xcountif }, /* 287 */
- X{ "FIND-IF", S, xfindif }, /* 288 */
- X{ "COERCE", S, xcoerce }, /* 289 */
- X{ "ELT", S, xelt }, /* 290 */
- X{ "MAP", S, xmap }, /* 291 */
- X{ "POSITION-IF", S, xpositionif }, /* 292 */
- X{ "SEARCH", S, xsearch }, /* 293 */
- X
- X*******************************
- X
- XIn file xlglob.c, add the following definition:
- X
- XLVAL s_elt = NIL;
- X
- X*******************************
- X
- XIn file xlinit.c, add the following external declaration:
- X
- Xextern LVAL s_elt;
- X
- Xin function xlsymbols(), in section "enter setf place specifiers", add
- X
- X s_elt = xlenter("ELT");
- X
- X*******************************
- X
- XIn file xlbfun.c, function xaref(), change
- X
- X array = xlgavector();
- X
- Xto
- X
- X array = xlgetarg();
- X
- XBefore the section titled "range check the index" add:
- X
- X if (stringp(array)) { /* extension -- allow fetching chars from string*/
- X if (i < 0 || i >= getslength(array)-1)
- X xlerror("string index out of bounds",index);
- X return (cvchar(array->n_string[i]));
- X }
- X
- X if (!vectorp(array)) xlbadtype(array); /* type must be array */
- X
- X******************************
- XIn xlcont.c, add the following declaration:
- X
- Xextern LVAL s_elt;
- X
- X
- XIn function placeform(), replace the fun == s_aref code with:
- X
- X xlsave1(arg1);
- X
- X arg1 = evarg(&place); /* allow string argument */
- X arg2 = evmatch(FIXNUM,&place); i = getfixnum(arg2);
- X if (place) toomany(place);
- X
- X if (stringp(arg1)) { /* extension for strings */
- X if (i < 0 || i >= getslength(arg1)-1)
- X xlerror("index out of range",arg2);
- X if (!charp(value))
- X xlerror("strings only contain characters",value);
- X arg1->n_string[i] = getchcode(value);
- X }
- X else if(vectorp(arg1)) {
- X if (i < 0 || i >= getsize(arg1))
- X xlerror("index out of range",arg2);
- X setelement(arg1,(int)i,value);
- X }
- X else xlbadtype(arg1);
- X xlpop();
- X
- XThen add the following "case":
- X
- X else if (fun == s_elt) {
- X xlsave1(arg1);
- X arg1 = evarg(&place);
- X arg2 = evmatch(FIXNUM,&place); i = getfixnum(arg2);
- X if (place) toomany(place);
- X if (listp(arg1)) {
- X for (; i > 0 && consp(arg1); --i)
- X arg1 = cdr(arg1);
- X if((!consp(arg1)) || i < 0)
- X xlerror("index out of range",arg2);
- X rplaca(arg1,value);
- X }
- X else if (ntype(arg1) == STRING) {
- X if (i < 0 || i >= getslength(arg1)-1)
- X xlerror("index out of range",arg2);
- X if (!charp(value))
- X xlerror("strings only contain characters",value);
- X arg1->n_string[i] = getchcode(value);
- X }
- X else if (ntype(arg1) == VECTOR) {
- X if (i < 0 || i >= getsize(arg1))
- X xlerror("index out of range",arg2);
- X setelement(arg1,(int)i,value);
- X }
- X else xlbadtype(arg1);
- X xlpop();
- X }
- X
- X***************************
- X
- XIn xlstr.c, function changecase(), change
- X
- X src = xlgastring();
- X
- Xto
- X
- X src = (destructive? xlgastring() : xlgastrorsym());
- X
- X
- XIn function strcompare(), change references to xlgastring to xlgastrorsym.
- X
- XIn function trim(), change references to xlgastring to xlgastrorsym.
- X
- X
- XDelete functions xstrcat() and xsubseq(). The latter is rewritten and
- Xwill be in a new file, xlseq.c
- X
- X****************************************
- XIn file xlsys.c, add the following:
- X
- Xint xlcvttype(arg) /* find type of argument and return it */
- XLVAL arg;
- X{
- X if (arg == a_subr) return SUBR;
- X if (arg == a_fsubr) return FSUBR;
- X if (arg == a_cons) return CONS;
- X if (arg == a_symbol) return SYMBOL;
- X if (arg == a_fixnum) return FIXNUM;
- X if (arg == a_flonum) return FLONUM;
- X if (arg == a_string) return STRING;
- X if (arg == a_object) return OBJECT;
- X if (arg == a_stream) return STREAM;
- X if (arg == a_vector) return VECTOR;
- X if (arg == a_closure) return CLOSURE;
- X if (arg == a_char) return CHAR;
- X if (arg == a_ustream) return USTREAM;
- X return 0;
- X}
- X
- XLOCAL LVAL listify(arg) /* arg must be vector or string */
- XLVAL arg;
- X{
- X LVAL val;
- X int i;
- X
- X xlsave1(val);
- X
- X if (ntype(arg) == VECTOR) {
- X for (i = getsize(arg); i-- > 0; )
- X val = cons(getelement(arg,i),val);
- X }
- X else { /* a string */
- X for (i = getslength(arg)-1; i-- > 0; )
- X val = cons(cvchar(arg->n_string[i]),val);
- X }
- X
- X xlpop();
- X return (val);
- X}
- X
- XLOCAL LVAL vectify(arg) /* arg must be string or cons */
- XLVAL arg;
- X{
- X LVAL val,temp;
- X int i,l;
- X
- X if (ntype(arg) == STRING) {
- X l = getslength(arg)-1;
- X val = newvector(l);
- X for (i=0; i < l; i++) setelement(val,i,cvchar(arg->n_string[i]));
- X }
- X else { /* a cons */
- X val = arg;
- X for (l = 0; consp(val); l++) val = cdr(val); /* get length */
- X val = newvector(l);
- X temp = arg;
- X for (i = 0; i < l; i++) {
- X setelement(val,i,car(temp));
- X temp = cdr(temp);
- X }
- X }
- X return val;
- X}
- X
- X
- XLOCAL LVAL stringify(arg) /* arg must be vector or cons */
- XLVAL arg;
- X{
- X LVAL val,temp;
- X int i,l;
- X
- X if (ntype(arg) == VECTOR) {
- X l = getsize(arg);
- X val = newstring(l+1);
- X for (i=0; i < l; i++) {
- X temp = getelement(arg,i);
- X if (ntype(temp) != CHAR) goto failed;
- X val->n_string[i] = getchcode(temp);
- X }
- X val->n_string[l] = 0;
- X return val;
- X }
- X else { /* must be cons */
- X val = arg;
- X for (l = 0; consp(val); l++) {
- X if (ntype(car(val)) != CHAR) goto failed;
- X val = cdr(val); /* get length */
- X }
- X
- X val = newstring(l+1);
- X temp = arg;
- X for (i = 0; i < l; i++) {
- X val->n_string[i] = getchcode(car(temp));
- X temp = cdr(temp);
- X }
- X val->n_string[l] = 0;
- X return val;
- X }
- Xfailed:
- X xlerror("cannot make into string", arg);
- X}
- X
- X
- X
- X/* coerce function */
- XLVAL xcoerce()
- X{
- X LVAL type, arg, temp;
- X int newtype,oldtype;
- X
- X arg = xlgetarg();
- X type = xlgetarg();
- X xllastarg();
- X
- X if ((newtype = xlcvttype(type)) == 0) goto badconvert;
- X
- X oldtype = ntype(arg);
- X if (oldtype == newtype) return (arg); /* easy case! */
- X
- X switch (newtype) {
- X case CONS: if ((oldtype == STRING)|(oldtype == VECTOR))
- X return (listify(arg));
- X break;
- X case STRING: if ((oldtype == CONS)|(oldtype == VECTOR))
- X return (stringify(arg));
- X break;
- X case VECTOR: if ((oldtype == STRING) | (oldtype == CONS))
- X return (vectify(arg));
- X break;
- X case CHAR:
- X if (oldtype == FIXNUM) return cvchar((int)getfixnum(arg));
- X else if ((oldtype == STRING) && (getslength(arg) == 2))
- X return cvchar(arg->n_string[0]);
- X else if (oldtype == SYMBOL) {
- X temp = getpname(arg);
- X if (getslength(temp) == 2) return cvchar(temp->n_string[0]);
- X }
- X break;
- X case FLONUM:
- X if (oldtype == FIXNUM) return (cvflonum(1.0*(int)getfixnum(arg)));
- X break;
- X }
- X
- X
- Xbadconvert:
- X xlerror("illegal coersion",arg);
- X
- X}
- X
- X
- X******************************
- X
- XIn file xllist.c, delete the functions xreverse(), xremove(), remif(),
- Xxremif(), xremifnot(), xdelete(), delif(), xdelif(), xdelifnot(), dotest1().
- XThese functions will be in the new file xlseq.c.
- X
- XRemove any LOCAL atribute to function dotest2().
- X
- X
- X******************************
- X
- XThis is the end of part 1.
- X
- X
- XFrom sce!mitel!uunet!zephyr.ens.tek.com!tekcrl!tekgvs!toma Sat Sep 16 08:20:33 EDT 1989
- XArticle: 3 of comp.lang.lisp.x
- XPath: cognos!sce!mitel!uunet!zephyr.ens.tek.com!tekcrl!tekgvs!toma
- XFrom: toma@tekgvs.LABS.TEK.COM (Tom Almy)
- XNewsgroups: comp.lang.lisp.x
- XSubject: XLISP 2.0 MODIFICATIONS (2 of 2)
- XMessage-ID: <5919@tekgvs.LABS.TEK.COM>
- XDate: 11 Sep 89 22:26:44 GMT
- XReply-To: toma@tekgvs.LABS.TEK.COM (Tom Almy)
- XOrganization: Tektronix, Inc., Beaverton, OR.
- XLines: 1073
- X
- XThe remainder of the changes consists of the file xlseq.c.
- X
- X
- XTom Almy
- XSeptember 11, 1989
- Xtoma@tekgvs.labs.tek.com
- XStandard Disclaimers Apply
- X
- X
- X******************************
- X
- X/* xlseq.c - xlisp sequence functions */
- X/* Written by Thomas Almy, based on code:
- X Copyright (c) 1985, by David Michael Betz
- X All Rights Reserved
- X Permission is granted for unrestricted non-commercial use */
- X
- X#include "xlisp.h"
- X
- X/* external procedures */
- Xextern int xlcvttype();
- Xextern int xlgkfixnum();
- Xextern int xlgetkeyarg();
- X
- X/* external variables */
- Xextern LVAL k_start,k_end,k_1start,k_1end,k_2start,k_2end;
- X
- X
- X/* Apologies from the author (Tom Almy):
- X :start and :end isn't quite Kosher in
- X that it doesn't always signal an error for out of range.
- X Fixing it up is left as an exercise for the reader.*/
- X
- X/* I desparately needed a "MAXINT" or "MAXLONG" constant, so I faked it*/
- X
- X/* Also, I found it convenient to use "goto" statements to handle non-local
- X loop exits and jumps to common error routines. A purist might complain,
- X but I think the code is cleaner and easier to follow this way. */
- X
- X#define MAXSIZE 10000000L /* a lie, but good enough */
- X
- XLOCAL VOID getseqbounds(start,end,length,startkey,endkey)
- Xlong *start, *end, length;
- XLVAL *startkey, *endkey;
- X{
- X LVAL arg;
- X
- X if (xlgkfixnum(*startkey,&arg)) {
- X *start = (long)getfixnum(arg);
- X if (*start < 0 || *start > length ) goto rangeError;
- X }
- X else *start = 0;
- X
- X if (xlgetkeyarg(*endkey, &arg) && arg != NIL) {
- X if (!fixp(arg)) xlbadtype(arg);
- X *end = (long)getfixnum(arg);
- X if (*end < 0 || *end > length) goto rangeError;
- X }
- X else *end = length; /* we need a maxint value! */
- X
- X if (*start <= *end) return;
- X /* else there is a range error */
- X
- XrangeError:
- X xlerror("range error",arg);
- X}
- X
- X
- X
- X/* dotest1 - call a test function with one argument */
- X/* this function was in xllist.c */
- Xint dotest1(arg,fun)
- X LVAL arg,fun;
- X{
- X LVAL *newfp;
- X
- X /* create the new call frame */
- X newfp = xlsp;
- X pusharg(cvfixnum((FIXTYPE)(newfp - xlfp)));
- X pusharg(fun);
- X pusharg(cvfixnum((FIXTYPE)1));
- X pusharg(arg);
- X xlfp = newfp;
- X
- X /* return the result of applying the test function */
- X return (xlapply(1) != NIL);
- X
- X}
- X
- X
- X/* xelt - sequence reference function */
- XLVAL xelt()
- X{
- X LVAL seq,index;
- X FIXTYPE i;
- X
- X /* get the sequence and the index */
- X
- X seq = xlgetarg();
- X
- X index = xlgafixnum(); i = getfixnum(index);
- X if (i < 0) goto badindex;
- X
- X xllastarg();
- X
- X if (listp(seq)) { /* do like nth, but check for in range */
- X /* find the ith element */
- X while (consp(seq)) {
- X if (i-- == 0) return (car(seq));
- X seq = cdr(seq);
- X }
- X goto badindex; /* end of list reached first */
- X }
- X
- X
- X if (ntype(seq) == STRING) {
- X if (i >= getslength(seq)-1) goto badindex;
- X return (cvchar(seq->n_string[i]));
- X }
- X
- X if (ntype(seq)!=VECTOR) xlbadtype(seq); /* type must be array */
- X
- X /* range check the index */
- X if (i >= getsize(seq)) goto badindex;
- X
- X /* return the array element */
- X return (getelement(seq,(int)i));
- X
- Xbadindex:
- X xlerror("index out of bounds",index);
- X}
- X
- X
- X/* xmap -- map function */
- X
- XLOCAL long getlength(seq)
- XLVAL seq;
- X{
- X long len;
- X
- X if (seq == NIL) return 0;
- X
- X switch (ntype(seq)) {
- X case STRING:
- X return (long)getslength(seq) - 1;
- X case VECTOR:
- X return (long)getsize(seq);
- X case CONS:
- X len = 0;
- X while (consp(seq)) {
- X len++;
- X seq = cdr(seq);
- X }
- X return len;
- X default:
- X xlbadtype(seq);
- X return (0); /* ha ha */
- X }
- X}
- X
- X
- XLVAL xmap()
- X{
- X LVAL *newfp, fun, lists, val, last, x, y;
- X long len,temp;
- X int argc, typ, i;
- X
- X /* protect some pointers */
- X xlstkcheck(3);
- X xlsave(fun);
- X xlsave(lists);
- X xlsave(val);
- X
- X /* get the type of resultant */
- X if ((last = xlgetarg()) == NIL) { /* nothing is returned */
- X typ = 0;
- X }
- X else if ((typ = xlcvttype(last)) != CONS &&
- X typ != STRING && typ != VECTOR) {
- X xlerror("invalid result type", last);
- X }
- X
- X /* get the function to apply and argument sequences */
- X fun = xlgetarg();
- X val = NIL;
- X lists = xlgetarg();
- X len = getlength(lists);
- X argc = 1;
- X
- X /* build a list of argument lists */
- X for (lists = last = consa(lists); moreargs(); last = cdr(last)) {
- X val = xlgetarg();
- X if ((temp = getlength(val)) < len) len = temp;
- X argc++;
- X rplacd(last,(cons(val,NIL)));
- X }
- X
- X /* initialize the result list */
- X switch (typ) {
- X case VECTOR: val = newvector(len); break;
- X case STRING: val = newstring(len+1); break;
- X default: val = NIL; break;
- X }
- X
- X
- X /* loop through each of the argument lists */
- X for (i=0;i<len;i++) {
- X
- X /* build an argument list from the sublists */
- X newfp = xlsp;
- X pusharg(cvfixnum((FIXTYPE)(newfp - xlfp)));
- X pusharg(fun);
- X pusharg(NIL);
- X for (x = lists; x != NIL ; x = cdr(x)) {
- X y = car(x);
- X switch (ntype(y)) {
- X case CONS:
- X pusharg(car(y));
- X rplaca(x,cdr(y));
- X break;
- X case VECTOR:
- X pusharg(getelement(y,i));
- X break;
- X case STRING:
- X pusharg(cvchar(y->n_string[i]));
- X break;
- X }
- X }
- X
- X /* apply the function to the arguments */
- X newfp[2] = cvfixnum((FIXTYPE)argc);
- X xlfp = newfp;
- X x = xlapply(argc);
- X
- X switch (typ) {
- X case CONS:
- X y = consa(x);
- X if (val) rplacd(last,y);
- X else val = y;
- X last = y;
- X break;
- X case VECTOR:
- X setelement(val,i,x);
- X break;
- X case STRING:
- X if (!charp(x))
- X xlerror("map function returned non-character",x);
- X val->n_string[i] = getchcode(x);
- X break;
- X }
- X
- X }
- X
- X /* restore the stack */
- X xlpopn(3);
- X
- X /* return the last test expression value */
- X return (val);
- X }
- X
- X
- X
- X
- X/* xconcatenate - concatenate a bunch of sequences */
- X/* replaces (and extends) strcat, now a macro */
- XLOCAL int calclength()
- X{
- X LVAL tmp, *saveargv;
- X int saveargc;
- X int len;
- X
- X /* save the argument list */
- X saveargv = xlargv;
- X saveargc = xlargc;
- X
- X /* find the length of the new string or vector */
- X for (len = 0; moreargs(); ) {
- X tmp = xlgetarg();
- X len += getlength(tmp);
- X if (len < 0) xlerror("too long",tmp);
- X }
- X
- X /* restore the argument list */
- X xlargv = saveargv;
- X xlargc = saveargc;
- X
- X return len;
- X}
- X
- X
- XLOCAL LVAL cattostring()
- X{
- X LVAL tmp,temp,val;
- X unsigned char *str;
- X int len,i;
- X
- X /* find resulting length -- also validates argument types */
- X len = calclength();
- X
- X /* create the result string */
- X val = newstring(len+1);
- X str = getstring(val);
- X
- X /* combine the strings */
- X while (moreargs()) {
- X tmp = nextarg();
- X if (tmp != NIL) switch (ntype(tmp)) {
- X case STRING:
- X len = getslength(tmp)-1;
- X memcpy((char *)str, (char *)getstring(tmp), len);
- X str += len;
- X break;
- X case VECTOR:
- X len = getsize(tmp);
- X for (i = 0; i < len; i++) {
- X temp = getelement(tmp,i);
- X if (!charp(temp)) goto failed;
- X *str++ = getchcode(temp);
- X }
- X break;
- X case CONS:
- X while (consp(tmp)) {
- X temp = car(tmp);
- X if (!charp(temp)) goto failed;
- X *str++ = getchcode(temp);
- X tmp = cdr(tmp);
- X }
- X break;
- X }
- X }
- X
- X *str = 0; /* delimit string (why, I don't know!) */
- X
- X /* return the new string */
- X return (val);
- X
- Xfailed:
- X xlerror("cannot make into string", tmp);
- X}
- X
- XLOCAL LVAL cattovector()
- X{
- X LVAL tmp,val;
- X LVAL *vect;
- X int len,i;
- X
- X /* find resulting length -- also validates argument types */
- X len = calclength();
- X
- X /* create the result vector */
- X val = newvector(len);
- X vect = &val->n_vdata[0];
- X
- X /* combine the vectors */
- X while (moreargs()) {
- X tmp = nextarg();
- X if (tmp != NIL) switch (ntype(tmp)) {
- X case VECTOR:
- X len = getsize(tmp);
- X memcpy(vect, &getelement(tmp,0), len*sizeof(LVAL));
- X vect += len;
- X break;
- X case STRING:
- X len = getslength(tmp)-1;
- X for (i = 0; i < len; i++) {
- X *vect++ = cvchar(tmp->n_string[i]);
- X }
- X break;
- X case CONS:
- X while (consp(tmp)) {
- X *vect++ = car(tmp);
- X tmp = cdr(tmp);
- X }
- X break;
- X }
- X }
- X
- X /* return the new vector */
- X return (val);
- X}
- X
- XLOCAL LVAL cattocons()
- X{
- X LVAL val,tmp,next,last=NIL;
- X int len,i;
- X
- X xlsave1(val); /* protect against GC */
- X
- X /* combine the lists */
- X while (moreargs()) {
- X tmp = nextarg();
- X if (tmp != NIL) switch (ntype(tmp)) {
- X case CONS:
- X while (consp(tmp)) {
- X next = consa(car(tmp));
- X if (val) rplacd(last,next);
- X else val = next;
- X last = next;
- X tmp = cdr(tmp);
- X }
- X break;
- X case VECTOR:
- X len = getsize(tmp);
- X for (i = 0; i<len; i++) {
- X next = consa(getelement(tmp,i));
- X if (val) rplacd(last,next);
- X else val = next;
- X last = next;
- X }
- X break;
- X case STRING:
- X len = getslength(tmp) - 1;
- X for (i = 0; i < len; i++) {
- X next = consa(cvchar(tmp->n_string[i]));
- X if (val) rplacd(last,next);
- X else val = next;
- X last = next;
- X }
- X break;
- X default:
- X xlbadtype(tmp); break; /* need default because no precheck*/
- X }
- X }
- X
- X xlpop();
- X
- X return (val);
- X
- X}
- X
- X
- XLVAL xconcatenate()
- X{
- X LVAL tmp;
- X
- X switch (xlcvttype(tmp = xlgetarg())) { /* target type of data */
- X case CONS: return cattocons();
- X case STRING: return cattostring();
- X case VECTOR: return cattovector();
- X default: xlerror("invalid result type", tmp);
- X }
- X}
- X
- X/* xsubseq - return a subsequence -- new version */
- X
- XLVAL xsubseq()
- X{
- X int start,end,len;
- X int srctype;
- X LVAL src,dst;
- X LVAL next,last=NIL;
- X
- X /* get sequence */
- X src = xlgetarg();
- X if (listp(src)) srctype = CONS;
- X else srctype=ntype(src);
- X
- X
- X /* get length */
- X switch (srctype) {
- X case STRING:
- X len = getslength(src) - 1;
- X break;
- X case VECTOR:
- X len = getsize(src);
- X break;
- X case CONS:
- X dst = src; /* use dst as temporary */
- X len = 0;
- X while (consp(dst)) {len++; dst = cdr(dst);}
- X break;
- X default:
- X xlbadtype(src);
- X }
- X
- X /* get the starting position */
- X dst = xlgafixnum(); start = (int)getfixnum(dst);
- X if (start < 0 || start > len)
- X xlerror("sequence index out of bounds",dst);
- X
- X /* get the ending position */
- X if (moreargs()) {
- X dst = xlgafixnum(); end = (int)getfixnum(dst);
- X if (end < 0 || end > len)
- X xlerror("sequence index out of bounds",dst);
- X }
- X else
- X end = len;
- X xllastarg();
- X
- X len = end - start;
- X
- X switch (srctype) { /* do the subsequencing */
- X case STRING:
- X dst = newstring(len+1);
- X memcpy(getstring(dst), getstring(src)+start, len);
- X dst->n_string[len] = 0;
- X break;
- X case VECTOR:
- X dst = newvector(len);
- X memcpy(dst->n_vdata, &src->n_vdata[start], sizeof(LVAL)*len);
- X break;
- X case CONS:
- X xlsave1(dst);
- X while (start--) src = cdr(src);
- X while (len--) {
- X next = consa(car(src));
- X if (dst) rplacd(last,next);
- X else dst = next;
- X last = next;
- X src = cdr(src);
- X }
- X xlpop();
- X break;
- X }
- X
- X /* return the substring */
- X return (dst);
- X}
- X
- X
- X/* xreverse - built-in function reverse -- new version */
- XLVAL xreverse()
- X{
- X LVAL seq,val;
- X int i,len;
- X
- X /* get the sequence to reverse */
- X seq = xlgetarg();
- X xllastarg();
- X
- X if (seq == NIL) return (NIL); /* empty argument */
- X
- X switch (ntype(seq)) {
- X case CONS:
- X /* protect pointer */
- X xlsave1(val);
- X
- X /* append each element to the head of the result list */
- X for (val = NIL; consp(seq); seq = cdr(seq))
- X val = cons(car(seq),val);
- X
- X /* restore the stack */
- X xlpop();
- X break;
- X case VECTOR:
- X len = getsize(seq);
- X val = newvector(len);
- X for (i = 0; i < len; i++)
- X setelement(val,i,getelement(seq,len-i-1));
- X break;
- X case STRING:
- X len = getslength(seq) - 1;
- X val = newstring(len+1);
- X for (i = 0; i < len; i++)
- X val->n_string[i] = seq->n_string[len-i-1];
- X val->n_string[len] = 0;
- X break;
- X default:
- X xlbadtype(seq); break;
- X }
- X
- X /* return the sequence */
- X return (val);
- X}
- X
- X
- X/* remif - common code for 'remove', 'remove-if', and 'remove-if-not' */
- XLOCAL LVAL remif(tresult,expr)
- X int tresult,expr;
- X{
- X LVAL x,seq,fcn,val,last,next;
- X int i,j,l;
- X long start,end;
- X
- X if (expr) {
- X /* get the expression to remove and the sequence */
- X x = xlgetarg();
- X seq = xlgetarg();
- X xltest(&fcn,&tresult);
- X }
- X else {
- X /* get the function and the sequence */
- X fcn = xlgetarg();
- X seq = xlgetarg();
- X/* xllastarg(); */
- X }
- X
- X if (seq == NIL) return NIL;
- X
- X getseqbounds(&start,&end,MAXSIZE,&k_start,&k_end);
- X
- X /* protect some pointers */
- X xlstkcheck(2);
- X xlprotect(fcn);
- X xlsave(val);
- X
- X /* remove matches */
- X
- X switch (ntype(seq)) {
- X case CONS:
- X end -= start; /* length */
- X for (; consp(seq); seq = cdr(seq)) {
- X
- X /* check to see if this element should be deleted */
- X /* force copy if count, as specified by end, is exhausted */
- X if (start-- > 0 || end-- <= 0 ||
- X (expr?dotest2(x,car(seq),fcn)
- X :dotest1(car(seq),fcn)) != tresult) {
- X next = consa(car(seq));
- X if (val) rplacd(last,next);
- X else val = next;
- X last = next;
- X }
- X }
- X break;
- X case VECTOR:
- X val = newvector(l=getlength(seq));
- X for (i=j=0; i < l; i++) {
- X if (i < start || i >= end || /* copy if out of range */
- X (expr?dotest2(x,getelement(seq,i),fcn)
- X :dotest1(getelement(seq,i),fcn)) != tresult) {
- X setelement(val,j++,getelement(seq,i));
- X }
- X }
- X if (l != j) { /* need new, shorter result -- too bad */
- X fcn = val; /* save value in protected cell */
- X val = newvector(j);
- X memcpy(val->n_vdata, fcn->n_vdata, j*sizeof(LVAL));
- X }
- X break;
- X case STRING:
- X l = getslength(seq)-1;
- X val = newstring(l+1);
- X for (i=j=0; i < l; i++) {
- X if (i < start || i >= end || /* copy if out of range */
- X (expr?dotest2(x,cvchar(seq->n_string[i]),fcn)
- X :dotest1(cvchar(seq->n_string[i]),fcn)) != tresult) {
- X val->n_string[j++] = seq->n_string[i];
- X }
- X }
- X if (l != j) { /* need new, shorter result -- too bad */
- X fcn = val; /* save value in protected cell */
- X val = newstring(j+1);
- X memcpy(val->n_string, fcn->n_string, j*sizeof(char));
- X val->n_string[j] = 0;
- X }
- X break;
- X default:
- X xlbadtype(seq); break;
- X }
- X
- X
- X /* restore the stack */
- X xlpopn(2);
- X
- X /* return the updated sequence */
- X return (val);
- X}
- X
- X/* xremif - built-in function 'remove-if' -- enhanced version */
- XLVAL xremif()
- X{
- X return (remif(TRUE,FALSE));
- X}
- X
- X/* xremifnot - built-in function 'remove-if-not' -- enhanced version */
- XLVAL xremifnot()
- X{
- X return (remif(FALSE,FALSE));
- X}
- X
- X/* xremove - built-in function 'remove' -- enhanced version */
- X
- XLVAL xremove()
- X{
- X return (remif(TRUE,TRUE));
- X}
- X
- X
- X/* delif - common code for 'delete', 'delete-if', and 'delete-if-not' */
- XLOCAL LVAL delif(tresult,expr)
- X int tresult,expr;
- X{
- X LVAL x,seq,fcn,last,val;
- X int i,j,l;
- X long start,end;
- X
- X if (expr) {
- X /* get the expression to delete and the sequence */
- X x = xlgetarg();
- X seq = xlgetarg();
- X xltest(&fcn,&tresult);
- X }
- X else {
- X /* get the function and the sequence */
- X fcn = xlgetarg();
- X seq = xlgetarg();
- X/* xllastarg(); */
- X }
- X
- X if (seq == NIL) return NIL;
- X
- X getseqbounds(&start,&end,MAXSIZE,&k_start,&k_end);
- X
- X /* protect a pointer */
- X xlstkcheck(1);
- X xlprotect(fcn);
- X
- X
- X /* delete matches */
- X
- X switch (ntype(seq)) {
- X case CONS:
- X end -= start; /* gives length */
- X /* delete leading matches */
- X while (consp(seq)) {
- X if (start-- > 0 || (expr?dotest2(x,car(seq),fcn)
- X :dotest1(car(seq),fcn)) != tresult)
- X break;
- X seq = cdr(seq);
- X }
- X val = last = seq;
- X
- X /* delete embedded matches */
- X if (consp(seq)) {
- X
- X /* skip the first non-matching element */
- X seq = cdr(seq);
- X
- X /* look for embedded matches */
- X while (consp(seq)) {
- X
- X /* check to see if this element should be deleted */
- X if (start-- <= 0 && end-- > 0 &&
- X (expr?dotest2(x,car(seq),fcn)
- X :dotest1(car(seq),fcn)) == tresult)
- X rplacd(last,cdr(seq));
- X else
- X last = seq;
- X
- X /* move to the next element */
- X seq = cdr(seq);
- X }
- X }
- X break;
- X case VECTOR:
- X l = getlength(seq);
- X for (i=j=0; i < l; i++) {
- X if (i < start || i >= end || /* copy if out of range */
- X (expr?dotest2(x,getelement(seq,i),fcn)
- X :dotest1(getelement(seq,i),fcn)) != tresult) {
- X if (i != j) setelement(seq,j,getelement(seq,i));
- X j++;
- X }
- X }
- X if (l != j) { /* need new, shorter result -- too bad */
- X fcn = seq; /* save value in protected cell */
- X seq = newvector(j);
- X memcpy(seq->n_vdata, fcn->n_vdata, j*sizeof(LVAL));
- X }
- X val = seq;
- X break;
- X case STRING:
- X l = getslength(seq)-1;
- X for (i=j=0; i < l; i++) {
- X if (i < start || i >= end || /* copy if out of range */
- X (expr?dotest2(x,cvchar(seq->n_string[i]),fcn)
- X :dotest1(cvchar(seq->n_string[i]),fcn)) != tresult) {
- X if (i != j) seq->n_string[j] = seq->n_string[i];
- X j++;
- X }
- X }
- X if (l != j) { /* need new, shorter result -- too bad */
- X fcn = seq; /* save value in protected cell */
- X seq = newstring(j+1);
- X memcpy(seq->n_string, fcn->n_string, j*sizeof(char));
- X seq->n_string[j] = 0;
- X }
- X val = seq;
- X break;
- X default:
- X xlbadtype(seq); break;
- X }
- X
- X
- X /* restore the stack */
- X xlpop();
- X
- X /* return the updated sequence */
- X return (val);
- X}
- X
- X/* xdelif - built-in function 'delete-if' -- enhanced version */
- XLVAL xdelif()
- X{
- X return (delif(TRUE,FALSE));
- X}
- X
- X/* xdelifnot - built-in function 'delete-if-not' -- enhanced version */
- XLVAL xdelifnot()
- X{
- X return (delif(FALSE,FALSE));
- X}
- X
- X/* xdelete - built-in function 'delete' -- enhanced version */
- X
- XLVAL xdelete()
- X{
- X return (delif(TRUE,TRUE));
- X}
- X
- X/* xcountif - built-in function 'count-if TAA MOD addition */
- XLVAL xcountif()
- X{
- X FIXTYPE counter=0;
- X int i,l;
- X long start,end;
- X LVAL seq, fcn;
- X
- X
- X /* get the arguments */
- X fcn = xlgetarg();
- X seq = xlgetarg();
- X/* xllastarg(); */
- X
- X if (seq == NIL) return (cvfixnum(0L));
- X
- X getseqbounds(&start,&end,MAXSIZE,&k_start,&k_end);
- X
- X xlstkcheck(1);
- X xlprotect(fcn);
- X
- X /* examine arg and count */
- X switch (ntype(seq)) {
- X case CONS:
- X end -= start;
- X for (; consp(seq); seq = cdr(seq))
- X if (start-- <= 0 && end-- > 0 &&
- X dotest1(car(seq),fcn)) counter++;
- X break;
- X case VECTOR:
- X l = getlength(seq);
- X if (end < l) l = end;
- X for (i=start; i < l; i++)
- X if (dotest1(getelement(seq,i),fcn)) counter++;
- X break;
- X case STRING:
- X l = getslength(seq)-1;
- X if (end < l) l = end;
- X for (i=start; i < l; i++)
- X if (dotest1(cvchar(seq->n_string[i]),fcn)) counter++;
- X break;
- X default:
- X xlbadtype(seq); break;
- X }
- X
- X xlpop();
- X
- X return (cvfixnum(counter));
- X}
- X
- X/* xfindif - built-in function 'find-if' TAA MOD */
- XLVAL xfindif()
- X{
- X LVAL seq, fcn, val;
- X long start,end;
- X int i,l;
- X
- X fcn = xlgetarg();
- X seq = xlgetarg();
- X/* xllastarg(); */
- X
- X if (seq == NIL) return NIL;
- X
- X getseqbounds(&start,&end,MAXSIZE,&k_start,&k_end);
- X
- X xlstkcheck(1);
- X xlprotect(fcn);
- X
- X switch (ntype(seq)) {
- X case CONS:
- X end -= start;
- X for (; consp(seq); seq = cdr(seq)) {
- X if (start-- <= 0 && end-- > 0 &&
- X dotest1(val=car(seq), fcn)) goto fin;
- X }
- X break;
- X case VECTOR:
- X l = getlength(seq);
- X if (end < l) l = end;
- X for (i=start; i < l; i++)
- X if (dotest1(val=getelement(seq,i),fcn)) goto fin;
- X break;
- X case STRING:
- X l = getslength(seq)-1;
- X if (end < l) l = end;
- X for (i=start; i < l; i++)
- X if (dotest1(val=cvchar(seq->n_string[i]),fcn)) goto fin;
- X break;
- X default:
- X xlbadtype(seq); break;
- X }
- X
- X val = NIL; /* not found */
- X
- Xfin:
- X xlpop();
- X return (val);
- X}
- X
- X/* xpositionif - built-in function 'position-if' TAA MOD */
- XLVAL xpositionif()
- X{
- X LVAL seq, fcn;
- X long start,end;
- X FIXTYPE count;
- X int i,l;
- X
- X fcn = xlgetarg();
- X seq = xlgetarg();
- X/* xllastarg(); */
- X
- X if (seq == NIL) return NIL;
- X
- X getseqbounds(&start,&end,MAXSIZE,&k_start,&k_end);
- X
- X xlstkcheck(1);
- X xlprotect(fcn);
- X
- X switch (ntype(seq)) {
- X case CONS:
- X end -= start;
- X count = 0;
- X for (; consp(seq); seq = cdr(seq)) {
- X if ((start-- <= 0) && (end-- > 0) &&
- X dotest1(car(seq), fcn)) goto fin;
- X count++;
- X }
- X break;
- X case VECTOR:
- X l = getlength(seq);
- X if (end < l) l = end;
- X for (i=start; i < l; i++)
- X if (dotest1(getelement(seq,i),fcn)) {
- X count = i;
- X goto fin;
- X }
- X break;
- X case STRING:
- X l = getslength(seq)-1;
- X if (end < l) l = end;
- X for (i=start; i < l; i++)
- X if (dotest1(cvchar(seq->n_string[i]),fcn)) {
- X count = i;
- X goto fin;
- X }
- X break;
- X default:
- X xlbadtype(seq); break;
- X }
- X
- X xlpop(); /* not found */
- X return(NIL);
- X
- Xfin: /* found */
- X xlpop();
- X return (cvfixnum(count));
- X}
- X
- X/* xsearch -- search function */
- X
- XLVAL xsearch()
- X{
- X LVAL seq1, seq2, fcn, temp1, temp2;
- X long start1, start2, end1, end2, len1, len2;
- X long i,j;
- X int tresult,typ1, typ2;
- X
- X /* get the sequences */
- X seq1 = xlgetarg();
- X len1 = getlength(seq1);
- X seq2 = xlgetarg();
- X len2 = getlength(seq2);
- X
- X /* test/test-not args? */
- X xltest(&fcn,&tresult);
- X
- X /* check for start/end keys */
- X getseqbounds(&start1,&end1,len1,&k_1start,&k_1end);
- X getseqbounds(&start2,&end2,len2,&k_2start,&k_2end);
- X
- X if (end2 - 1 + (start1 - end1) > len2) {
- X end2 = len2 + 1 - (start1 - end1);
- X if (end2 < start2) end2 = start2;
- X }
- X
- X len1 = end1 - start1; /* calc lengths of sequences to test */
- X
- X typ1 = ntype(seq1);
- X typ2 = ntype(seq2);
- X
- X xlstkcheck(1);
- X xlprotect(fcn);
- X
- X if (typ1 == CONS) { /* skip leading section of sequence 1 if a cons */
- X j = start1;
- X while (j--) seq1 = cdr(seq1);
- X }
- X
- X if (typ2 == CONS) { /* second string is cons */
- X i = start2; /* skip leading section of string 2 */
- X while (start2--) seq2 = cdr(seq2);
- X
- X for (;i<end2;i++) {
- X temp2 = seq2;
- X if (typ1 == CONS) {
- X temp1 = seq1;
- X for (j = start1; j < end1; j++) {
- X if (dotest2(car(temp1),car(temp2),fcn) != tresult)
- X goto next1;
- X temp1 = cdr(temp1);
- X temp2 = cdr(temp2);
- X }
- X }
- X else {
- X for (j = start1; j < end1; j++) {
- X if (dotest2(typ1 == VECTOR ? getelement(seq1,j)
- X : cvchar(seq1->n_string[j]),
- X car(temp2), fcn) != tresult)
- X goto next1;
- X temp2 = cdr(temp2);
- X }
- X }
- X xlpop();
- X return cvfixnum(i);
- X next1: /* continue */
- X seq2 = cdr(seq2);
- X }
- X }
- X
- X else for (i = start2; i < end2 ; i++) { /* second string is array/string */
- X if (typ1 == CONS) {
- X temp1 = seq1;
- X for (j = 0; j < len1; j++) {
- X if (dotest2(car(temp1),
- X typ2 == VECTOR ? getelement(seq2,i+j)
- X : cvchar(seq2->n_string[i+j]),
- X fcn) != tresult)
- X goto next2;
- X temp1 = cdr(temp1);
- X }
- X }
- X else for (j=start1; j < end1; j++) {
- X if (dotest2(typ1 == VECTOR ? getelement(seq1,j)
- X : cvchar(seq1->n_string[j]),
- X typ2 == VECTOR ? getelement(seq2,i+j-start1)
- X : cvchar(seq2->n_string[i+j-start1]),
- X fcn) != tresult)
- X goto next2;
- X }
- X xlpop();
- X return cvfixnum(i);
- X next2:; /* continue */
- X }
- X
- X xlpop();
- X return (NIL); /*no match*/
- X
- X}
- X
- X
- XEND OF PART 2
- X
- X
- SHAR_EOF
- if test 41338 -ne "`wc -c 'xl-cl001.fix'`"
- then
- echo shar: error transmitting "'xl-cl001.fix'" '(should have been 41338 characters)'
- fi
- echo shar: extracting "'xl-xs001.bug'" '(2766 characters)'
- if test -f 'xl-xs001.bug'
- then
- echo shar: over-writing existing file "'xl-xs001.bug'"
- fi
- sed 's/^X//' << \SHAR_EOF > 'xl-xs001.bug'
- XFrom sce!mitel!uunet!mcvax!kth!draken!liuida!mikpe Fri Apr 14 14:35:35 EDT 1989
- XArticle: 85 of comp.lang.lisp.x
- XPath: cognos!sce!mitel!uunet!mcvax!kth!draken!liuida!mikpe
- XFrom: mikpe@senilix.ida.liu.se (Mikael Pettersson)
- XNewsgroups: comp.lang.lisp.x
- XSubject: X{scheme,lisp} bugs
- XSummary: operating on closed files can cause NULL dereferences
- XMessage-ID: <1244@senilix.ida.liu.se>
- XDate: 13 Apr 89 04:13:07 GMT
- XOrganization: CIS Dept, Univ of Linkoping, Sweden
- XLines: 61
- X
- X
- XI stumbled across a bug in Xscheme's handling of ports. It turns out
- Xthat none of the functions that take ports as arguments check whether
- Xthe port is open (i.e. it hasn't been closed) (except xclose() itself!).
- XSending a closed port to e.g. READ causes a NULL dereference down in
- Xthe OS specific stuff: on my UNIX machine Xscheme dies with a SIGSEGV.
- XThe easiest fix (although it has the side-effect of making PORT? return #F
- Xfor closed ports) is to change the portp() macro in xscheme.h like this:
- X
- X*** xscheme.h.~1~ Sun Feb 19 13:25:29 1989
- X--- xscheme.h Wed Apr 12 18:41:26 1989
- X***************
- X*** 207,213 ****
- X #define consp(x) ((x) && ntype(x) == CONS)
- X #define stringp(x) ((x) && ntype(x) == STRING)
- X #define symbolp(x) ((x) && ntype(x) == SYMBOL)
- X! #define portp(x) ((x) && ntype(x) == PORT)
- X #define objectp(x) ((x) && ntype(x) == OBJECT)
- X #define fixp(x) ((x) && ntype(x) == FIXNUM)
- X #define floatp(x) ((x) && ntype(x) == FLONUM)
- X--- 207,213 ----
- X #define consp(x) ((x) && ntype(x) == CONS)
- X #define stringp(x) ((x) && ntype(x) == STRING)
- X #define symbolp(x) ((x) && ntype(x) == SYMBOL)
- X! #define portp(x) ((x) && ntype(x) == PORT && getfile(x))
- X #define objectp(x) ((x) && ntype(x) == OBJECT)
- X #define fixp(x) ((x) && ntype(x) == FIXNUM)
- X #define floatp(x) ((x) && ntype(x) == FLONUM)
- X
- X
- XI then went to see if Xlisp was equally fragile, but luckily it wasn't.
- XOnly xformat() (due to it's checking for NIL, T and unnamed streams)
- Xmisses to check that the file is open.
- XThe following patch fixes that problem (your line numbers may vary):
- X
- X*** xlfio.c.~1~ Mon Dec 19 06:07:30 1988
- X--- xlfio.c Wed Apr 12 20:35:40 1989
- X***************
- X*** 410,416 ****
- X else {
- X if (stream == true)
- X stream = getvalue(s_stdout);
- X! else if (!streamp(stream) && !ustreamp(stream))
- X xlbadtype(stream);
- X val = NIL;
- X }
- X--- 410,420 ----
- X else {
- X if (stream == true)
- X stream = getvalue(s_stdout);
- X! else if (streamp(stream)) { /* copied from xlgetfile() */
- X! if (getfile(stream) == NULL)
- X! xlfail("file not open");
- X! }
- X! else if (!ustreamp(stream))
- X xlbadtype(stream);
- X val = NIL;
- X }
- X--
- XMikael Pettersson, Dept of Comp & Info Sci, University of Linkoping, Sweden
- Xemail: mpe@ida.liu.se or ..!{mcvax,munnari,uunet}!enea!liuida!mpe
- X
- X
- SHAR_EOF
- if test 2766 -ne "`wc -c 'xl-xs001.bug'`"
- then
- echo shar: error transmitting "'xl-xs001.bug'" '(should have been 2766 characters)'
- fi
- # End of shell archive
- exit 0
- --
- Gary Murphy uunet!mitel!sce!cognos!garym
- (garym%cognos.uucp@uunet.uu.net)
- (613) 738-1338 x5537 Cognos Inc. P.O. Box 9707 Ottawa K1G 3N3
- "There are many things which do not concern the process" - Joan of Arc
-
-